import ast
import logging
import json
import requests
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework.authentication import TokenAuthentication
from rest_framework.parsers import JSONParser
from rest_framework.views import APIView

from api_test.common.api_response import JsonResponse
from websocket import create_connection

logger = logging.getLogger(__name__)  # 这里使用 __name__ 动态搜索定义的 logger 配置，这里有一个层次关系的知识点。


class HttpProtocol(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = ()

    @swagger_auto_schema(request_body=openapi.Schema(
        type=openapi.TYPE_OBJECT,
        required=['url', 'method', 'body'],
        properties={
            'url': openapi.Schema(type=openapi.TYPE_STRING, description="url地址 eg.http://www.baidu.com/s"),
            'method': openapi.Schema(type=openapi.TYPE_STRING, description="请求方法 eg. get/post"),
            'body': openapi.Schema(type=openapi.TYPE_OBJECT, description="请求参数 "),
        },
    ))
    def post(self, request):
        """
        普通http/https协议请求
        """
        try:
            data = JSONParser().parse(request)
            url = data['url']
            body = data["body"]
            header = data["header"]
            if data["method"].lower() == "get":
                r = requests.get(url, params=body)
            elif data["method"].lower() == "post":
                r = requests.post(url, json=body, headers=header)
            elif data["method"].lower() == "put":
                r = requests.put(url, data=body, headers=header)
            elif data["method"].lower() == "delete":
                r = requests.delete(url, data=body, headers=header)
            try:
                return JsonResponse(data={"data": json.loads(r.text), "status": str(r.status_code) + " " + str(r.reason)}, code="999999", msg="成功")
            except:
                return JsonResponse(data={"data": r.text, "status": str(r.status_code) + " " + str(r.reason)}, code="999999", msg="成功")
        except Exception as e:
            return JsonResponse(data={"errmsg": str(e)}, code="999995", msg="失败")


class WebsocketProtocol(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = ()

    @swagger_auto_schema(request_body=openapi.Schema(
        type=openapi.TYPE_OBJECT,
        required=['url', 'body'],
        properties={
            'url': openapi.Schema(type=openapi.TYPE_STRING, description="url地址 eg.ws://test.xwordbuddies.com/ws"),
            'body': openapi.Schema(type=openapi.TYPE_OBJECT, description="请求参数"),
            'login': openapi.Schema(type=openapi.TYPE_OBJECT, description="请求参数，body参数依赖的登录请求参数"),
        },
    ))
    def post(self, request):
        """
        websocket+json协议请求
        """
        # {"url":"ws://test.xwordbuddies.com:80/ws",
        # "body": {"account":"0d0d68fa-be71-4a6a-9aea-a8c7bee2ff89","account_type":"visitor",
        # "additional":"{\"device_id\":null,\"channel\":\"ios\",\"appver\":\"1.0.0\"}","name":"Login","nickname":"","photo":"","state":0}}
        # "body":{"name":"LabourUnionSearch", "blurry_name":["test"]}
        try:
            data = JSONParser().parse(request)

            # url = data['protocol'] + "://" + data["ip"] + data["port"] + data["path"]
            url = data['url']
            ws = create_connection(url)
            assert ws.status == 101

            trans_name = data["body"]["name"]
            # TODO
            if trans_name not in ['Login'] and 'login' not in data:
                data["login"] = {"account":"0d0d68fa-be71-4a6a-9aea-a8c7bee2ff89","account_type":"visitor","additional":"{\"device_id\":null,\"channel\":\"ios\",\"appver\":\"1.0.0\"}","name":"Login","nickname":"","photo":"","state":0}

            if "login" in data:
                ws.send(str(data["login"]))   # send传字符串 ， 返回也是str，需转dict
                ws.recv()

            ws.send(str(data["body"]))

            game_message_list = []
            while True:
                body_res = ws.recv()
                body_res = ast.literal_eval(body_res)
                # real_resp_name = body_res["name"]
                # print(real_resp_name)
                game_message_list.append(body_res)
                if body_res["name"] == trans_name:
                    break
            return JsonResponse(data={"data": game_message_list, "status": ws.status}, code="999999", msg="成功")
        except Exception as e:
            return JsonResponse(code="999990", msg="失败", data={"error": str(e)})
